package com.cos.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cos.entity.OrderDetailEntity;
import com.cos.exception.StockMsg;
import com.cos.exception.vo.StockException;
import com.cos.feign.api.AddressFeign;
import com.cos.feign.api.OrderFeign;
import com.cos.feign.api.StockFeign;
import com.cos.interceptor.DynamicDataSource;
import com.cos.service.OrderDetailService;
import com.cos.utils.OidUtils;
import com.cos.utils.ThreadPoolUtils;
import com.cos.vo.AddressEntity;
import com.cos.vo.Car;
import com.cos.vo.OrderParam;
import com.cos.vo.StockParam;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.cos.mapper.OrdersMapper;
import com.cos.entity.OrdersEntity;
import com.cos.service.OrdersService;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;


@Service("ordersService")
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, OrdersEntity> implements OrdersService {

    @Autowired
    private OrderFeign orderFeign;
    @Autowired
    private AddressFeign addressFeign;
    @Autowired
    private OrderDetailService orderDetailService;
    @Autowired
    private OidUtils oidUtils;
    @Autowired
    private DynamicDataSource dataSource;
    @Autowired
    private StockFeign stockFeign;
    @Override
    @Transactional //添加两个表开启本地事务
    public String createOrder(OrderParam orderParam, Integer uid) throws ExecutionException, InterruptedException {
        ThreadPoolExecutor pool = ThreadPoolUtils.getPoolExecutor();
        //从当前线程找那个获取当前表的编号
        Integer tableIndex = dataSource.threadLocal();
        //获取地址
        CompletableFuture<AddressEntity> futureAddress = CompletableFuture.supplyAsync(() -> {
            //根据id查询用户地址
            AddressEntity addressById = addressFeign.getAddressById(orderParam.getAddressId());
            return addressById;
        }, pool);
        //查询购物车
        CompletableFuture<Map<String, Object>> futureCar = CompletableFuture.supplyAsync(() -> {
            List<String> split = Arrays.asList(orderParam.getGid().split(","));
            Map<String, Object> map = null;
            if (!StringUtils.isEmpty(orderParam.getGid())) {
                map = orderFeign.getCarByUidAndPid(uid, split);
            } else {
                map = orderFeign.getCarByUid(uid);
            }
            BigDecimal subPrice = BigDecimal.valueOf(Long.valueOf(map.get("subPrice").toString()));
            List<Map<String, Object>> carList = (List<Map<String, Object>>) map.get("carList");

            //将查到的数据转为json字符串
            String s = JSON.toJSONString(carList);
            //再将json转换为car的对象的集合
            List<Car> list = JSON.parseArray(s, Car.class);
            //将购物车信息再次封装成map集合 因为有两个对象
            Map<String, Object> mapCar = new HashMap<>();
            mapCar.put("subPrice", subPrice);
            mapCar.put("carList", list);
            return map;
        }, pool);

        //将两个线程关联
        CompletableFuture<Void> allOf = CompletableFuture.allOf(futureAddress, futureCar);
        Void aVoid = allOf.get();//阻塞 等待上面商量个线程完成

        //启用一个线程扣减库存
        CompletableFuture<String> supplyAsync = CompletableFuture.supplyAsync(() -> {
            try {
                //扣减库存
                List<Car> carList = (List<Car>) futureCar.get().get("carList");
                String s = JSON.toJSONString(carList);
                List<Car> carList1 = JSON.parseArray(s,Car.class);
                List<StockParam> stockParamList = new ArrayList<>();
                for (Car car : carList1) {
                    StockParam stockParam = new StockParam(car.getGid(), car.getSum(), 1);
                    stockParamList.add(stockParam);
                }
                boolean b = stockFeign.updateStock(stockParamList);
                return b;
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
            return false;
        }, pool)
           .thenApplyAsync((stockFlag)->{
               if (stockFlag) {
                   //如果为true就创建订单
                   try {
                       //扣减库存
                       List<Car> carList1 = (List<Car>) futureCar.get().get("carList");
                       String s = JSON.toJSONString(carList1);
                       List<Car> carList = JSON.parseArray(s,Car.class);
                       //获取地址详情
                       AddressEntity  addressEntity = futureAddress.get();
                       //获取总价
                       BigDecimal subPrice = BigDecimal.valueOf(Long.valueOf(futureCar.get().get("subPrice").toString())) ;
                       //给订单赋值
                       OrdersEntity ordersEntity = new OrdersEntity();
                       ordersEntity.setOid(oidUtils.createOrderId(uid));
                       ordersEntity.setCreateTime(new Date());
                       ordersEntity.setToltalprice(subPrice);
                       ordersEntity.setName(addressEntity.getName());
                       ordersEntity.setAddress(addressEntity.getAddress());
                       ordersEntity.setUid(addressEntity.getUid());
                       ordersEntity.setPhone(addressEntity.getPhone());
                       ordersEntity.setStatus(2);
                       ordersEntity.setPayType(1);
                       //添加订单库存
                        baseMapper.insertOrder(ordersEntity, tableIndex);
                       List<OrderDetailEntity> list1=new ArrayList<>();
                       //给商品详情赋值
                       for (Car car : carList) {
                           OrderDetailEntity orderDetailEntity = new OrderDetailEntity();
                           orderDetailEntity.setGid(car.getGid());
                           orderDetailEntity.setGdesc(car.getGoods().getGdesc());
                           orderDetailEntity.setGname(car.getGoods().getGname());
                           orderDetailEntity.setGpng(car.getGoods().getGpng());
                           orderDetailEntity.setSum(car.getSum());
                           orderDetailEntity.setOid(oidUtils.createOrderId(uid));
                           orderDetailEntity.setGprice(car.getGoods().getGprice());
                           orderDetailEntity.setSubtotal(BigDecimal.valueOf(Long.valueOf(car.getSum())).multiply(car.getGoods().getGprice()));
                           list1.add(orderDetailEntity);
                       }
                       //添加商品详情
                       orderDetailService.insertOrderDetail(list1, tableIndex);
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   } catch (ExecutionException e) {
                       e.printStackTrace();
                   }
                   return oidUtils.createOrderId(uid);
               }else {
                   return null;
               }
           },pool);

        String oid =  supplyAsync.get();
        if (StringUtils.isEmpty(oid)) {
            throw  new StockException(StockMsg.UNLOCK_STOCK_ERROP);
        }
        return oid;
//        List<String> split = Arrays.asList(orderParam.getGid().split(","));
//        Map<String,Object> map=null;
//        if ( !StringUtils.isEmpty(orderParam.getGid())) {
//            map= orderFeign.getCarByUidAndPid(uid, split);
//        }else {
//            map= orderFeign.getCarByUid(uid);
//        }
//        BigDecimal subPrice = BigDecimal.valueOf(Long.valueOf(map.get("subPrice").toString())) ;
//        List<Map<String,Object>> carList = (List<Map<String, Object>>) map.get("carList");
//
//        //将查到的数据转为json字符串
//        String s = JSON.toJSONString(carList);
//        //再将json转换为car的对象的集合
//        List<Car> list = JSON.parseArray(s,Car.class);
//        //根据id查询用户地址
//        AddressEntity addressById = addressFeign.getAddressById(orderParam.getAddressId());
//        //给订单赋值
//        OrdersEntity ordersEntity=new OrdersEntity();
//        ordersEntity.setOid(oidUtils.createOrderId(uid));
//        ordersEntity.setCreateTime(new Date());
//        ordersEntity.setToltalprice(subPrice);
//        ordersEntity.setName(addressById.getName());
//        ordersEntity.setAddress(addressById.getAddress());
//        ordersEntity.setUid(addressById.getUid());
//        ordersEntity.setPhone(addressById.getPhone());
//        ordersEntity.setStatus(2);
//        ordersEntity.setPayType(1);
//        //从当前线程找那个获取当前表的编号
//        Integer tableIndex = dataSource.threadLocal();
//        //添加订单库存
//        baseMapper.insertOrder(ordersEntity,tableIndex);
//        List<OrderDetailEntity> list1=new ArrayList<>();
//        //给商品详情赋值
//        for (Car car : list) {
//            OrderDetailEntity orderDetailEntity=new OrderDetailEntity();
//            orderDetailEntity.setGid(car.getGid());
//            orderDetailEntity.setGdesc(car.getGoods().getGdesc());
//            orderDetailEntity.setGname(car.getGoods().getGname());
//            orderDetailEntity.setGpng(car.getGoods().getGpng());
//            orderDetailEntity.setSum(car.getSum());
//            orderDetailEntity.setOid(oidUtils.createOrderId(uid));
//            orderDetailEntity.setGprice(car.getGoods().getGprice());
//            orderDetailEntity.setSubtotal(BigDecimal.valueOf(Long.valueOf(car.getSum())).multiply(car.getGoods().getGprice()));
//            list1.add(orderDetailEntity);
//        }
//        //添加商品详情
//        orderDetailService.insertOrderDetail(list1,tableIndex);
//
//        //扣减库存
//        List<StockParam> stockParamList=new ArrayList<>();
//        for (OrderDetailEntity entity : list1) {
//            StockParam stockParam=new StockParam(entity.getGid(),entity.getSum(),1);
//            stockParamList.add(stockParam);
//        }
//        boolean b = stockFeign.updateStock(stockParamList);
//        if (!b) {
//            //如果扣减库存失败抛出异常
//            throw new StockException(StockMsg.UNLOCK_STOCK_ERROP);
//        }
//        return oidUtils.createOrderId(uid) ;

    }
}